﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/11/5 16:03:28
 * ************************************************************/
namespace Mozlite.Data.MySqlDataProvider
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.Data.Common;
    using System.Collections.Generic;
    using Mozlite.Common;
    using MySql.Data.MySqlClient;

    /// <summary>
    /// 数据库提供者。
    /// </summary>
    public class MySqlSecurityDataProvider : SecurityDataProvider
    {
        /// <summary>
        /// 初始化类<see cref="T:Mozlite.Data.MySqlDataProvider.MySqlSecurityDataProvider"/>。
        /// </summary>
        public MySqlSecurityDataProvider() : base(MySqlClientFactory.Instance) { }

        #region roles
        public override void AddRoles(List<UserRole> roles)
        {
            var transaction = GetTransaction();
            try
            {
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE UserID = {1};", AddProfix("userinroles"), roles.First<UserRole>().UserID));
                foreach (var role in roles)
                {
                    ExecuteNonQuery("INSERT INTO {0}(SettingsID, UserID, RoleID, CreateDate, EnabledDate, ExpiredDate)VALUES('{1}', '{2}', '{3}', '{4}', '{5}', '{6}');", AddProfix("userinroles"), role.SettingsID, role.UserID, role.RoleID, role.CreateDate, role.EnabledDate, role.ExpiredDate);
                }
                transaction.CommitTransaction();
            }
            catch {
                transaction.RollbackTransaction();
            }
        }

        public override bool SaveRole(Role role)
        {
            if(role.RoleID>0)
                return ExecuteNonQuery("REPLACE INTO {0}(`SettingsID`,`RoleID`,`RoleName`,`Description`,`IsHidden`,`LogoUrl`,`DisplayColor`,`RoleLevel`,`SortOrder`)VALUES('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}');", AddProfix("Roles"), Q(role.SettingsID), Q(role.RoleID), Q(role.RoleName), Q(role.Description), Q(role.IsHidden), Q(role.LogoUrl), Q(role.DisplayColor), Q(role.RoleLevel), Q(role.SortOrder));
            return ExecuteNonQuery("INSERT INTO {0}(`SettingsID`,`RoleName`,`Description`,`IsHidden`,`LogoUrl`,`DisplayColor`,`RoleLevel`,`SortOrder`)VALUES('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}');", AddProfix("Roles"), Q(role.SettingsID), Q(role.RoleName), Q(role.Description), Q(role.IsHidden), Q(role.LogoUrl), Q(role.DisplayColor), Q(role.RoleLevel), Q(role.SortOrder));
        }

        public override Dictionary<int, Role> LoadRoles(int settingsID)
        {
            Dictionary<int, Role> roles = new Dictionary<int, Role>();
            using (var reader = ExecuteReader("SELECT * FROM {0} WHERE SettingsID = '{1}';", AddProfix("Roles"), settingsID)) {
                while (reader.Read())
                    roles.Add(reader.GetInt32("RoleID"), new Role(reader));
                reader.Close();
            }
            return roles;
        }

        public override bool DeleteRoles(int settingsID, string roleIDs)
        {
            var transaction = GetTransaction();
            try
            {
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE SettingsID = '{1}' AND RoleID IN({2});", AddProfix("UserInRoles"), settingsID, Q(roleIDs)));
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE SettingsID = '{1}' AND RoleID IN({2});", AddProfix("Roles"), settingsID, Q(roleIDs)));
                transaction.CommitTransaction();
                return true;
            }
            catch {
                transaction.RollbackTransaction();
            }
            return false;
        }

        public override Role GetRole(int settingsID, int roleID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE SettingsID = '{1}' AND RoleID = '{2}';", AddProfix("Roles"), settingsID, roleID).TGet<Role>();
        }

        public override List<Role> GetRoles(int settingsID, int userID)
        {
            return ExecuteReader("SELECT r.* FROM {0} r INNER JOIN {1} ur ON r.RoleID = ur.RoleID AND r.SettingsID = ur.SettingsID WHERE ur.SettingsID = '{2}' AND ur.UserID = '{3}';", AddProfix("Roles"), AddProfix("UserInRoles"), settingsID, userID).TGetList<Role>();
        }

        public override Dictionary<int, UserRole> GetUserRoles(int settingsID, int userID)
        {
            var roles = new Dictionary<int, UserRole>();
            using (var reader = ExecuteReader("SELECT * FROM {0} WHERE SettingsID = '{1}' AND UserID = '{2}';", AddProfix("UserInRoles"), settingsID, userID)) {
                while (reader.Read())
                    roles.Add(reader.GetInt32("UserID"), new UserRole(reader));
                reader.Close();
            }
            return roles;
        }

        public override void AddRoles(int settingsID, int userID, string roleIDs, DateTime enabledDate, DateTime expiredDate)
        {
            ExecuteNonQuery(@"INSERT INTO {0}(SettingsID, UserID, RoleID, CreateDate, EnabledDate, ExpiredDate)
            SELECT SettingsID, {2}, RoleID, now(), '{3}', '{4}'
            FROM {5} r
            WHERE r.SettingsID = '{1}' AND r.RoleID IN({6});", AddProfix("UserInRoles"), settingsID, userID, Q(enabledDate), Q(expiredDate), AddProfix("Roles"), Q(roleIDs)); 
        }

        public override void RemoveRoles(int settingsID, int userID, string roleIDs)
        {
            ExecuteNonQuery("DELETE FROM {0} WHERE SettingsID = {1} AND UserID = {2} AND RoleID IN({3});", AddProfix("UserInRoles"), settingsID, userID, Q(roleIDs));
        }
        #endregion

        #region currencies
        public override bool SaveCurrency(Currency currency)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteCurrency(int settingsID, int currencyID)
        {
            throw new NotImplementedException();
        }

        public override Currency GetCurrency(int settingsID, int currencyID)
        {
            throw new NotImplementedException();
        }

        public override Dictionary<string, Currency> LoadCurrencies(int settingsID)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region users
        public override List<string> GetUsers(int settingsID, int roleID)
        {
            var users = new List<string>();
            using (var reader = ExecuteReader("SELECT UserName FROM {0} u INNER JOIN {1} ur ON u.UserID = ur.UserID WHERE ur.SettingsID = {2} AND ur.RoleID = {3};", AddProfix("Users"), AddProfix("UserInRoles"), settingsID, roleID))
            {
                while (reader.Read())
                    users.Add(reader.GetString("UserName"));
                reader.Close();
            }
            return users;
        }

        public override int GetRoleID(int settingsID, string roleName)
        {
            return ExecuteScalar<int>("SELECT RoleID FROM {0} WHERE SettingsID = '{1}' AND RoleName = '{2}';", AddProfix("Roles"), settingsID, Q(roleName));
        }

        public override CreateUserStatus EditUser(User user, bool uniqueEmail)
        {
            throw new NotImplementedException();
        }

        public override CreateUserStatus CreateUser(User user, bool uniqueEmail, Guid publicKey)
        {
            if (ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE UserName = '{1}' OR NickName = '{1}';", AddProfix("Users"), Q(user.UserName)))
                return CreateUserStatus.DuplicateUserName;
            if (uniqueEmail&&ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE Email = '{1}';", AddProfix("Users"), Q(user.Email)))
                return CreateUserStatus.DuplicateEmailAddress;
            if (publicKey != Guid.Empty && !ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE PublicKey = '{1}';", AddProfix("UserInvitations"), Q(publicKey)))
                return CreateUserStatus.InvalidInvitationKey;
            var transaction = GetTransaction();
            try
            {
               user.UserID = ExecuteScalar<int>(transaction, string.Format(@"INSERT INTO {0}( `UserName`, `NickName`, `Password`, `Email`, `EncryptType`, `PasswordQuestion`, `PasswordAnswer`, `AccountStatus`, `PasswordSalt`, `LastLockoutDate`, `LastLoginDate`, `IsAnonymous`, `CreateDate`, `CreateIP`, `LastLoginIP`, `LastActiveDate`, `LastPasswordChangedDate`, `FailedPasswordAnswerAttemptCount`, `FailedPasswordAnswerAttemptWindowStart`, `FailedPasswordAttemptCount`, `FailedPasswordAttemptWindowStart`, `BannedUntil`, `BannedReason`, `TimeZone`, `Gender`, `BirthYear`, `BirthMonth`, `BirthDay`, `Avatar`, `DateFormat`, `TimeFormat`, `Extensions`) 
                                         VALUES('{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}', '{12}', '{13}', '{14}', '{15}', '{16}', '{17}', '{18}', '{19}', '{20}', '{21}', '{22}', '{23}', '{24}', '{25}', '{26}', '{27}', '{28}', '{29}', '{30}', '{31}', '{32}');select last_insert_id();", AddProfix("Users"),
                                         Q(user.UserName), Q(user.NickName), Q(user.Password), Q(user.Email), Q(user.EncryptType), Q(user.PasswordQuestion), Q(user.PasswordAnswer), Q(user.AccountStatus), Q(user.PasswordSalt), Q(user.LastLockoutDate), Q(user.LastLoginDate), Q(user.IsAnonymous), DateTime.Now, Q(user.CreateIP), Q(user.LastLoginIP), DateTime.Now, DateTime.Now, 0, DateTime.Now.AddDays(-1), 0, DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-1), Q(BannedReason.Other), Q(user.TimeZone), Q(user.Gender), 0, 0, 0, Q(user.Avatar), Q(user.DateFormat), Q(user.TimeFormat), Q(user.ToString())));

                if (publicKey != Guid.Empty)
                    ExecuteNonQuery(transaction, string.Format(@"DELETE FROM {0} WHERE PublicKey = '{0}';", AddProfix("UserInvitations"), Q(publicKey)));

                transaction.CommitTransaction();
                return CreateUserStatus.Created;
            }
            catch {
                transaction.RollbackTransaction();
            }
            return CreateUserStatus.UnknownFailure;
        }

        public override void ChangePassword(int userID, string password)
        {
            ExecuteNonQuery("UPDATE {0} SET `Password` = '{1}', LastPasswordChangedDate = now() WHERE UserID = {2};", AddProfix("Users"), Q(password), userID);
        }

        public override void ChangeSecurityQuestAndAnswer(int userID, string question, string answer)
        {
            ExecuteNonQuery("UPDATE {0} SET `Question` = '{1}', `Answer` = '{2}', LastPasswordChangedDate = now() WHERE UserID = {3};", AddProfix("Users"), Q(question), Q(answer), userID);
        }

        public override DateTime SetUserLastActivity(int userID, string lastAction)
        {
            throw new NotImplementedException();
        }

        public override User GetUser(int userID, string userName, string email, bool isOnline)
        {
            string where = null;
            if (userID > 0)
                where += "UserID = " + userID;
            else if (!string.IsNullOrEmpty(userName))
                where += "UserName = '" + Q(userName) + "'";
            else if (!string.IsNullOrEmpty(email))
                where += "Email = '" + Q(email) + "'";
            if (where == null)
                return null;
            return ExecuteReader("SELECT * FROM {0} WHERE {1}", AddProfix("Users"), where).TGet<User>();
        }

        public override void SetLogin(int userID, string ip)
        {
            ExecuteNonQuery("UPDATE {0} SET LastLoginIP = '{1}', LastLoginDate = now() WHERE UserID = '{2}';", AddProfix("Users"), Q(ip), Q(userID));
        }

        public override bool SetValidFailure(User user)
        {
            if (user.IsLockedOut)
                return ExecuteNonQuery("UPDATE {0} SET AccountStatus = '{1}', LastLockoutDate = now(), BannedUntil = '{3}', BannedReason = '{4}' WHERE UserID = '{2}';", AddProfix("Users"), Q(user.AccountStatus), user.UserID, Q(user.BannedUntil), Q(user.BannedReason));
            else if(user.FailedPasswordAttemptCount == 0)
                return ExecuteNonQuery("UPDATE {0} SET FailedPasswordAttemptCount = 1, FailedPasswordAttemptWindowStart = now() WHERE UserID = '{2}';", AddProfix("Users"), user.UserID);
            else
                return ExecuteNonQuery("UPDATE {0} SET FailedPasswordAttemptCount = FailedPasswordAttemptCount + 1 WHERE UserID = '{2}';", AddProfix("Users"), user.UserID);
        }

        public override bool DeleteUsers(string userIDs)
        {
            var transaction = GetTransaction();
            try
            {
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE UserID IN({1});", AddProfix("UserProfiles"), Q(userIDs)));
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE UserID IN({1});", AddProfix("UserInRoles"), Q(userIDs)));
                ExecuteNonQuery(transaction, string.Format("DELETE FROM {0} WHERE UserID IN({1});", AddProfix("Users"), Q(userIDs)));
                transaction.CommitTransaction();
                return true;
            }
            catch { transaction.RollbackTransaction(); }
            return false;
        }

        public override int GetUserIDByEmail(string email)
        {
            return ExecuteScalar<int>("SELECT UserID FROM {0} WHERE Email = '{1}';", AddProfix("Users"), Q(email)); 
        }

        public override int GetUserIDByUserName(string userName)
        {
            return ExecuteScalar<int>("SELECT UserID FROM {0} WHERE UserName = '{1}';", AddProfix("Users"), Q(userName)); 
        }

        public override bool SaveAvatar(int userID, string avatar)
        {
            return ExecuteNonQuery("UPDATE {0} SET Avatar = '{1}' WHERE UserID = '{2}';", AddProfix("Users"), Q(avatar));
        }

        public override CreateUserStatus SaveProfile(User user)
        {
            if (ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE (UserName = '{1}' OR NickName = '{1}') AND UserID <> {2};", AddProfix("Users"), Q(user.NickName), user.UserID))
                return CreateUserStatus.DuplicateNickName;
            if (ExecuteNonQuery("UPDATE {0} SET NickName = '{1}', Gender = '{2}', BirthDay = '{3}', BirthMonth = '{4}', BirthYear = '{5}', TimeZone = '{6}', Avatar = '{9}', Extensions = '{7}' WHERE UserID = '{8}';",
                AddProfix("Users"), Q(user.NickName), Q(user.Gender), user.BirthDay, user.BirthMonth, user.BirthYear, Q(user.TimeZone), Q(user.ToString()), user.UserID, Q(user.Avatar)))
                return CreateUserStatus.Updated;
            return CreateUserStatus.UnknownFailure;
        }

        public override bool SetAccountStatus(int userid, AccountStatus status, DateTime bannedUntil, BannedReason reason)
        {
            if(status != AccountStatus.Banned)
                return ExecuteNonQuery("UPDATE {0} SET AccountStatus = '{1}' WHERE UserID = '{2}';", AddProfix("Users"), Q(status), userid);
            else
                return ExecuteNonQuery("UPDATE {0} SET AccountStatus = '{1}', LastLockoutDate = now(), BannedUntil = '{3}', BannedReason = '{4}'  WHERE UserID = '{2}';", AddProfix("Users"), Q(status), userid, Q(bannedUntil), Q(reason));
        }
        #endregion

        #region search
        /// <summary>
        /// 检索用户。
        /// </summary>
        /// <param name="query">用户查询实例对象。</param>
        /// <param name="size">返回所有用户记录数。</param>
        /// <returns>返回用户列表。</returns>
        public override List<User> Search(UserQuery query, out int size)
        {
            List<User> users = new List<User>();
            string fromSet;
            string where = query.GetWhere(new Func<string, string>(AddProfix), out fromSet);
            string sql = @"SELECT u.UserID, UserName, Gender, u.CreateDate, LastActiveDate, LastLoginIP
FROM {0} 
WHERE {1} 
ORDER BY {2}
{3};
SELECT COUNT(*) 
FROM {0} 
WHERE {1};";
            using (IDataReader reader = ExecuteReader(sql, fromSet, where, query.OrderBy, query.IsDesc ? "DESC" : null))
            {
                while (reader.Read())
                {
                    User user = new User();
                    user.UserID = reader.GetInt32("UserID");
                    user.UserName = reader.GetString("UserName");
                    user.Gender = reader.TGet<Gender>("Gender");
                    user.CreateDate = reader.GetDateTime("CreateDate");
                    user.LastActiveDate = reader.GetDateTime("LastActiveDate");
                    user.LastLoginIP = reader.GetString("LastLoginIP");
                    users.Add(user);
                }
                size = reader.GetSize();
                reader.Close();
            }
            return users;
        }
        #endregion

        #region user invitations
        public override void GeneralUserInvitations(int userID, int count, int expiredDays)
        {
            var transactions = GetTransaction();
            try
            {
                for (var i = 0; i < count; i++)
                {
                    ExecuteNonQuery(transactions, string.Format("INSERT INTO {0}(PublicKey, UserID, EnabledDate, ExpiredDate)VALUES('{1}', '{2}', now(), '{3}');", AddProfix("UserInvitations"), userID, count, DateTime.Now.AddDays(expiredDays)));
                }
                transactions.CommitTransaction();
            }
            catch { }
            transactions.RollbackTransaction();
        }

        public override List<UserInvitation> GetUserInitations(int userID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE UserID = {1};", AddProfix("UserInvitations"), userID).TGetList<UserInvitation>();
        }

        public override bool DeleteUserInitations(int userID, bool expired)
        {
            if (userID > 0)
                return ExecuteNonQuery("DELETE FROM {0} WHERE UserID = {1};", AddProfix("UserInvitations"), userID);
            else if(expired)
                return ExecuteNonQuery("DELETE FROM {0} WHERE EnabledDate <= now();", AddProfix("UserInvitations"));
            return true;
        }
        #endregion

        #region permissions
        public override bool CopyPermissionSchema(int settingsID, Guid targetSchemaID, string schemaName, string schemaDescription)
        {
            return ExecuteNonQuery(@"INSERT INTO {0}(SettingsID, SchemaID, SchemaName, Description, LastModified, PermissionType)
            SELECT SettingsID, '{1}', '{2}', '{3}', now(), PermissionType)
            FROM {0} WHERE SettingsID = '{4}' AND SchemaID = '{5}';", AddProfix("PermissionSchemas"), Q(Guid.NewGuid()), Q(schemaName), Q(schemaDescription), settingsID, Q(targetSchemaID));
        }

        public override bool CreatePermissionSchema(PermissionSchema permissionSchema)
        {
            return ExecuteNonQuery("INSERT IGNORE INTO {0}(SettingsID, SchemaID, SchemaName, Description, LastModified, PermissionType)VALUES('{1}', '{2}', '{3}', '{4}', now(), '{5}');", AddProfix("PermissionSchemas"),
                permissionSchema.SettingsID, permissionSchema.SchemaID, Q(permissionSchema.SchemaName), Q(permissionSchema.Description), Q(permissionSchema.PermissionType));
        }

        public override bool DeletePermissionSchema(int settingsID, Guid schemaID)
        {
            return ExecuteNonQuery("DELETE FROM {0} WHERE SettingsID = '{1}' AND SchemaID = '{2}';DELETE FROM {3} WHERE SettingsID = '{1}' AND SchemaID = '{2}';", AddProfix("Permissions"), settingsID, Q(schemaID), AddProfix("PermissionSchemas"));
        }

        public override Dictionary<Guid, PermissionSchema> GetAllPermissionSchemas(int settingsID, string permissionInstanceType)
        {
            var schemas = new Dictionary<Guid, PermissionSchema>();
            using (var reader = ExecuteReader("SELECT * FROM {0} WHERE SettingsID = {1} AND PermissionType = '{2}';", AddProfix("PermissionSchemas"), settingsID, Q(permissionInstanceType)))
            {
                while (reader.Read())
                    schemas.Add(reader.GetGuid("SchemaID"), new PermissionSchema(reader));
                reader.Close();
            }
            return schemas;
        }

        public override bool SavePermissions(List<PermissionBase> permissions)
        {
            var transaction = GetTransaction();
            try
            {
                foreach (var permission in permissions)
                {
                    ExecuteNonQuery(transaction, string.Format("REPLACE INTO {0}(SettingsID, SchemaID, RoleID, Permissions)VALUES('{1}', '{2}', '{3}', '{4}');", AddProfix("Permissions"), permission.SettingsID, permission.SchemaID, permission.RoleID, Q(Globals.ConvertObjectToString(permission))));
                }
                transaction.CommitTransaction();
                return true;
            }
            catch {
                transaction.RollbackTransaction();
            }
            return false;
        }

        public override Dictionary<Guid, Dictionary<int, T>> GetAllPermissions<T>(int settingsID)
        {
            var permissions = new Dictionary<Guid, Dictionary<int, T>>();
            using (var reader = ExecuteReader("SELECT p.* FROM {0} p INNER JOIN {1} s ON p.SettingsID = s.SettingsID AND p.SchemaID = s.SchemaID WHERE s.SettingsID = {2} AND s.PermissionType = '{3}';", AddProfix("Permissions"), AddProfix("PermissionSchemas"), settingsID, Q(typeof(T).GetInstanceType())))
            {
                while (reader.Read())
                {
                    var permission = PermissionBase.GetPermission<T>(reader);
                    if (permission == null)
                        continue;
                    if (!permissions.ContainsKey(permission.SchemaID))
                        permissions.Add(permission.SchemaID, new Dictionary<int, T>());
                    permissions[permission.SchemaID].Add(permission.RoleID, permission);
                }
                reader.Close();
            }
            return permissions;
        }

        public override bool UpdatePermissionSchema(PermissionSchema permissionSchema)
        {
            return ExecuteNonQuery("UPDATE {0} SET SchemaName = '{1}', Description = '{2}', LastModified = now() WHERE SettingsID = '{3}' AND SchemaID = '{4}';", AddProfix("PermissionSchemas"), Q(permissionSchema.SchemaName), Q(permissionSchema.Description), permissionSchema.SettingsID, Q(permissionSchema.SchemaID));
        }

        public override Dictionary<Guid, PermissionSchema> LoadPermissionSchemas(int settingsID)
        {
            var schemas = new Dictionary<Guid, PermissionSchema>();
            using (var reader = ExecuteReader("SELECT * FROM {0} WHERE SettingsID = '{1}';", AddProfix("PermissionSchemas"), settingsID))
            {
                while (reader.Read())
                    schemas.Add(reader.GetGuid("SchemaID"), new PermissionSchema(reader));
                reader.Close();
            }
            return schemas;
        }

        public override PermissionSchema GetPermissionSchema(int settingsID, Guid schemaID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE SettingsID = '{1}' AND SchemaID = '{2}';", AddProfix("PermissionSchemas"), settingsID, Q(schemaID)).TGet<PermissionSchema>();
        }
        #endregion

        #region profiles
        public override bool SaveProfile(UserProfile profile)
        {
            if (ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE UserID = {1} AND SettingsID = {2};", AddProfix("UserProfiles"), profile.UserID, profile.SettingsID))
            {
                return ExecuteNonQuery("UPDATE {0} SET Extensions = '{3}' WHERE UserID = {1} AND SettingsID = {2};", AddProfix("UserProfiles"), profile.UserID, profile.SettingsID, Q(profile.ToString()));
            }
            return ExecuteNonQuery("INSERT INTO {0}(UserID, SettingsID, Extensions)VALUES({1}, {2}, '{3}');", AddProfix("UserProfiles"), profile.UserID, profile.SettingsID, Q(profile.ToString()));
        }

        public override UserProfile GetProfile(int settingsID, int userID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE SettingsID = {1} AND UserID = {2};", AddProfix("UserProfiles"), settingsID, userID).TGet<UserProfile>();
        }
        #endregion

        public override bool SetGlobalAdministrator(int userID, bool isGlobalAdministrator)
        {
            return ExecuteNonQuery("UPDATE {0} SET IsGlobalAdministrator = {1} WHERE UserID = {2};", AddProfix("Users"), Q(isGlobalAdministrator), userID);
        }
    }
}